package com.arlib.floatingsearchview;

/**
 * Copyright (C) 2015 Ari C.
 * <p/>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p/>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p/>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import com.arlib.floatingsearchview.suggestions.SearchSuggestionsAdapter;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Image;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.ListContainer;
import ohos.agp.components.Text;
import ohos.agp.components.TextField;
import ohos.agp.components.element.Element;
import ohos.app.Context;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 * A search UI widget that implements a floating search box also called persistent
 * search.
 */
public class FloatingSearchView extends DirectionalLayout {
    private static ListContainer listContainer;

    private static Image ivBack;

    private static OnSuggestionClickListener onSuggestionClickListener;

    private static List<String> suggestionsList = new ArrayList<>();

    private static String searchedItem = "";

    private static String floatingSearchHint = "Search ...";

    private static int floatingSearchBarMarginLeft = 0;

    private static int floatingSearchBarMarginTop = 0;

    private static int floatingSearchBarMarginRight = 0;

    private static int suggestion;

    private DirectionalLayout dlSuggestion;

    private DirectionalLayout search_query_section;

    private TextField mSearchInput;

    /**
     * SearchResultsListAdapter Constructor
     *
     * @param context context of ability
     * @param attrSet for attribute set
     */
    public FloatingSearchView(Context context, AttrSet attrSet) {
        super(context, attrSet);
        applyXmlAttributes(attrSet);
    }

    /**
     * SearchResultsListAdapter Constructor
     *
     * @param context     context of ability
     * @param attrSet     for attribute set
     * @param suggestions items list
     */

    public FloatingSearchView(Context context, AttrSet attrSet, List<String> suggestions) {
        super(context, attrSet, null);
        FloatingSearchView.suggestionsList = suggestions;
    }

    private void applyXmlAttributes(AttrSet attrSet) {
        Component rootView = LayoutScatter.getInstance(getContext())
                .parse(ResourceTable.Layout_floating_search_layout, null, false);
        Component mSearchInputComp = rootView.findComponentById(ResourceTable.Id_search_bar_text);
        if (mSearchInputComp instanceof TextField) {
            mSearchInput = (TextField) mSearchInputComp;
        }
        Component listContainerComp = rootView.findComponentById(ResourceTable.Id_suggestions_list);
        if (listContainerComp instanceof ListContainer) {
            listContainer = (ListContainer) listContainerComp;
        }
        Component ivBackComp = rootView.findComponentById(ResourceTable.Id_iv_back);
        if (ivBackComp instanceof Image) {
            ivBack = (Image) ivBackComp;
        }
        Component dlSuggestionComp = rootView.findComponentById(ResourceTable.Id_dl_suggestion);
        if (dlSuggestionComp instanceof DirectionalLayout) {
            dlSuggestion = (DirectionalLayout) dlSuggestionComp;
        }
        Component search_query_sectionComp = rootView.findComponentById(ResourceTable.Id_search_query_section);
        if (search_query_sectionComp instanceof DirectionalLayout) {
            search_query_section = (DirectionalLayout) search_query_sectionComp;
        }

        if (attrSet.getAttr("floatingSearch_searchHint").isPresent()) {
            floatingSearchHint = attrSet.getAttr("floatingSearch_searchHint").get().getStringValue();
            mSearchInput.setHint(floatingSearchHint);
        }

        ComponentContainer.LayoutConfig config = createLayoutConfig(attrSet);
        //  dlSuggestion.setLayoutConfig(config);
        search_query_section.setLayoutConfig(config);

        mSearchInput.setClickedListener(new ClickedListener() {
            @Override
            public void onClick(Component component) {
                searchedItem = mSearchInput.getText();
                if (ivBack.getVisibility() != VISIBLE) {
                    mSearchInput.setText("");
                    ivBack.setVisibility(VISIBLE);
                }
                if (searchedItem.isEmpty()) {
                    listContainer.setVisibility(VISIBLE);
                    mSearchInput.setText("");
                }
            }
        });

        ivBack.setClickedListener(new ClickedListener() {
            @Override
            public void onClick(Component component) {
                ivBack.setVisibility(HIDE);
                listContainer.setVisibility(HIDE);
                mSearchInput.setText("");
            }
        });

        setFocusChangedListenerForSearchInput();
        addTextObserverForSearchInput();
        addComponent(rootView);
    }

    private void setFocusChangedListenerForSearchInput() {
        mSearchInput.setFocusChangedListener(new FocusChangedListener() {
            @Override
            public void onFocusChange(Component component, boolean focus) {
                if (focus) {
                    SearchSuggestionsAdapter listItemProvider = new SearchSuggestionsAdapter(getContext(),
                            getSuggestions(suggestion),
                            new SearchSuggestionsAdapter.OnItemClicklistener() {
                                @Override
                                public void onItemClick(String selectedItem) {
                                    onSuggestionClickListener.onSuggestionClick(selectedItem);
                                    mSearchInput.setText(selectedItem);
                                    listContainer.setVisibility(HIDE);
                                    ivBack.setVisibility(HIDE);
                                    mSearchInput.clearFocus();
                                }
                            });
                    listContainer.setItemProvider(listItemProvider);
                }
            }
        });
    }

    private void addTextObserverForSearchInput() {
        mSearchInput.addTextObserver(new Text.TextObserver() {
            @Override
            public void onTextUpdated(String inputText, int index, int i1, int i2) {
                if (inputText.length() > 0) {
                    int textlength = inputText.length();
                    ArrayList<String> tempArrayList = new ArrayList<String>();
                    for (String currentItem : suggestionsList) {
                        if (textlength <= suggestionsList.size()) {
                            if (currentItem.toLowerCase(Locale.getDefault())
                                    .contains(inputText.toLowerCase(Locale.getDefault()))) {
                                tempArrayList.add(currentItem);
                                if (ivBack.getVisibility() == VISIBLE) {
                                    listContainer.setVisibility(VISIBLE);
                                } else {
                                    listContainer.setVisibility(HIDE);
                                }
                            }
                        }
                    }

                    SearchSuggestionsAdapter searchSuggestionsAdapter = new SearchSuggestionsAdapter(getContext(),
                            tempArrayList, new SearchSuggestionsAdapter.OnItemClicklistener() {
                        @Override
                        public void onItemClick(String selectedItem) {
                            if (onSuggestionClickListener != null) {
                                listContainer.setVisibility(HIDE);
                                onSuggestionClickListener.onSuggestionClick(selectedItem);
                                ivBack.setVisibility(HIDE);
                                mSearchInput.setText(selectedItem);
                                mSearchInput.clearFocus();
                            }
                        }
                    });
                    listContainer.setItemProvider(searchSuggestionsAdapter);
                } else {
                    handleZeroTextInput();
                }
            }
        });
    }

    private void handleZeroTextInput() {
        SearchSuggestionsAdapter listItemProvider = new SearchSuggestionsAdapter(getContext(),
                getSuggestions(suggestion),
                new SearchSuggestionsAdapter.OnItemClicklistener() {
                    @Override
                    public void onItemClick(String selectedItem) {
                        onSuggestionClickListener.onSuggestionClick(selectedItem);
                        ivBack.setVisibility(HIDE);
                        mSearchInput.setText(selectedItem);
                        listContainer.setVisibility(HIDE);
                        mSearchInput.clearFocus();
                    }
                });
        listContainer.setItemProvider(listItemProvider);
    }

    private ComponentContainer.LayoutConfig createLayoutConfig(AttrSet attrSet) {
        ComponentContainer.LayoutConfig config = new ComponentContainer.LayoutConfig(
                ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_CONTENT);
        if (attrSet.getAttr("floatingSearch_searchBarMarginLeft").isPresent()) {
            floatingSearchBarMarginLeft = attrSet.getAttr("floatingSearch_searchBarMarginLeft").get().getIntegerValue();
            config.setMarginLeft(floatingSearchBarMarginLeft);
        }

        if (attrSet.getAttr("floatingSearch_searchBarMarginTop").isPresent()) {
            floatingSearchBarMarginTop = attrSet.getAttr("floatingSearch_searchBarMarginTop").get().getIntegerValue();
            config.setMarginTop(floatingSearchBarMarginTop);
        }

        if (attrSet.getAttr("floatingSearch_searchBarMarginRight").isPresent()) {
            floatingSearchBarMarginRight = attrSet.getAttr("floatingSearch_searchBarMarginRight")
                    .get()
                    .getIntegerValue();
            config.setMarginRight(floatingSearchBarMarginRight);
        }
        return config;
    }

    /**
     * method for initialization
     *
     * @param onSuggestionClickListener for attribute set
     * @param count                     for suggestion list count
     */

    public static void init(int count, OnSuggestionClickListener onSuggestionClickListener) {
        FloatingSearchView.onSuggestionClickListener = onSuggestionClickListener;
        FloatingSearchView.suggestion = count;
    }

    /**
     * Interface for suggestion click
     */
    public interface OnSuggestionClickListener {
        /**
         * Called when the alert is set to be dismissed with an animation.
         *
         * @param alert the alert
         */
        void onSuggestionClick(String alert);
    }

    /**
     * method for getsuggestions
     *
     * @param count for number of suggestions
     * @return string list
     */
    private static List<String> getSuggestions(int count) {
        List<String> suggestionList = new ArrayList<>();
        String colorSuggestion;
        for (String currentItem : suggestionsList) {
            colorSuggestion = currentItem;
            suggestionList.add(colorSuggestion);
            if (suggestionList.size() == count) {
                break;
            }
        }
        return suggestionList;
    }
}